package com.wutong.engine.application;

import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.localization.Language;
import com.wutong.engine.anything.Config;
import com.wutong.engine.anything.GameLogger;
import com.wutong.engine.entity.GameEntity;
import javafx.scene.input.KeyCode;
import kotlin.Unit;
import org.slf4j.Logger;

import java.util.*;

import static com.almasb.fxgl.dsl.FXGLForKtKt.*;

/**
 * @author 王益凡
 */
public class GameEngine extends GameApplication {

    private final static Logger log = GameLogger.getLogger(GameEngine.class);

    private final static Map<String, Object> CONFIG_MAP = new HashMap<>();
    private final static ArrayList<GameEntity> ENTITIES = new ArrayList<>();

    @Override
    protected void initSettings(GameSettings gameSettings) {
        log.info("初始化游戏设置");
        // 加载配置
        log.info("已保存配置加载中...");
        Map<String, Object> loadMap = Config.loadJsonToMap("NormalSetting");
        loadMap.forEach((k, v) -> CONFIG_MAP.merge(k, v, (v1, v2) -> v1));
        if (!CONFIG_MAP.isEmpty()) {
            // 加载设置内容
            this.setConfig(gameSettings);
            // 更新配置
            Config.saveJsonByMap("NormalSetting", CONFIG_MAP);
            // TODO: 读取静态配置文件获取作者，版本号，游戏名称，游戏图标
        } else {
            log.warn("未修改任何配置，将以空载形式加载游戏");
        }
        log.info("初始化游戏设置完成");
    }

    @Override
    protected void initUI() {
        log.info("初始化游戏界面");
        log.info("初始化游戏界面完成");
    }

    @Override
    protected void initInput() {
        log.info("初始化输入监听");
        onKeyDown(KeyCode.SPACE, () -> {
            log.info("空格键按下");
            return Unit.INSTANCE;
        });
        onKeyUp(KeyCode.SPACE, () -> {
            log.info("空格键释放");
            return Unit.INSTANCE;
        });
        log.info("初始化输入监听完毕");
    }

    @Override
    protected void initGame() {
        log.info("初始化游戏...");
        ENTITIES.forEach(gameEntity -> {
            if (Optional.ofNullable(gameEntity.getAnimation()).isPresent()) {
                gameEntity.getAnimation().loadAnimationChannel();
            }
            gameEntity.createEntity();
        });
        log.info("初始化游戏完成");
    }

    public void loadEntity(ArrayList<GameEntity> gameEntityArrayList) {
        ENTITIES.addAll(gameEntityArrayList);
    }

    public void loadEntity(GameEntity... gameEntityArrayList) {
        if (gameEntityArrayList.length != 0) {
            log.debug("载入实体");
            ENTITIES.addAll(List.of(gameEntityArrayList));
        }
    }

    private Object getConfig(String key) {
        return CONFIG_MAP.getOrDefault(key, null);
    }

    private Language toLanguage(String language) {
        if (language == null) {
            return Language.ENGLISH;
        }
        return switch (language) {
            case "CHINESE" -> Language.CHINESE;
            case "FRENCH" -> Language.FRENCH;
            case "GERMAN" -> Language.GERMAN;
            case "ITALIAN" -> Language.ITALIAN;
            case "JAPANESE" -> Language.JAPANESE;
            case "KOREAN" -> Language.KOREAN;
            case "PORTUGUESE" -> Language.PORTUGUESE;
            case "RUSSIAN" -> Language.RUSSIAN;
            case "SPANISH" -> Language.SPANISH;
            case "TURKISH" -> Language.TURKISH;
            case "UKRAINIAN" -> Language.UKRAINIAN;
            case "VIETNAMESE" -> Language.VIETNAMESE;
            case "ARABIC" -> Language.ARABIC;
            case "HEBREW" -> Language.HEBREW;
            case "INDONESIAN" -> Language.INDONESIAN;
            case "DUTCH" -> Language.DUTCH;
            case "NORWEGIAN" -> Language.NORWEGIAN;
            case "SWEDISH" -> Language.SWEDISH;
            case "FINNISH" -> Language.FINNISH;
            case "HUNGARIAN" -> Language.HUNGARIAN;
            case "CZECH" -> Language.CZECH;
            case "ROMANIAN" -> Language.ROMANIAN;
            case "GREEK" -> Language.GREEK;
            default -> Language.ENGLISH;
        };
    }

    private void setConfig(GameSettings gameSettings) {
        gameSettings.setWidth((int) getConfig("width"));
        gameSettings.setHeight((int) getConfig("height"));
        gameSettings.setTitle((String) getConfig("title"));
        gameSettings.setVersion((String) getConfig("version"));
        gameSettings.setManualResizeEnabled((boolean) getConfig("isManualResizeEnabled"));
        if (getConfig("language") != null) {
            gameSettings.setDefaultLanguage(toLanguage(((Language) getConfig("language")).getName()));
        }
        if (getConfig("fontGame") != null) {
            gameSettings.setFontGame((String) getConfig("fontGame"));
        }
        if (getConfig("fontUi") != null) {
            gameSettings.setFontUI((String) getConfig("fontUi"));
        }
        if (getConfig("fontMono") != null) {
            gameSettings.setFontMono((String) getConfig("fontMono"));
        }
        if (getConfig("fontText") != null) {
            gameSettings.setFontText((String) getConfig("fontText"));
        }
        if (getConfig("fontSizeScaleUi") != null) {
            gameSettings.setFontSizeScaleUI((double) getConfig("fontSizeScaleUi"));
        }
        log.info("修改游戏配置完毕");
    }

    public void setWindowsSize(int width, int height, boolean isManualResizeEnabled) {
        CONFIG_MAP.put("width", width);
        CONFIG_MAP.put("height", height);
        CONFIG_MAP.put("isManualResizeEnabled", isManualResizeEnabled);
        log.info("设置窗口大小为 {} x {}, 是否允许自由缩放：{}", width, height, isManualResizeEnabled);
    }

    public void setWindowsSize(int width, int height) {
        this.setWindowsSize(width, height, false);
    }

    public void setLanguage(Language language) {
        CONFIG_MAP.put("language", language);
        log.info("修改语言为：{}", language.getNativeName());
    }

    public void setFont(String fontGame, String fontUi, String fontMono, String fontText, double fontSizeScaleUi) {
        CONFIG_MAP.put("fontGame", fontGame);
        CONFIG_MAP.put("fontUi", fontUi);
        CONFIG_MAP.put("fontMono", fontMono);
        CONFIG_MAP.put("fontText", fontText);
        CONFIG_MAP.put("fontSizeScaleUi", fontSizeScaleUi);
        log.info("设置字体：{}，{}，{}，{}，UI字体大小缩放：{}", fontGame, fontUi, fontMono, fontText, fontSizeScaleUi);
    }

    public void setFont(String fontGame, String fontUi, String fontMono, String fontText) {
        CONFIG_MAP.put("fontGame", fontGame);
        CONFIG_MAP.put("fontUi", fontUi);
        CONFIG_MAP.put("fontMomo", fontMono);
        CONFIG_MAP.put("fontText", fontText);
        log.info("设置字体：{}，{}，{}，{}", fontGame, fontUi, fontMono, fontText);
    }

    public Map<String, Object> getConfigMap() {
        return CONFIG_MAP;
    }

    public void launchGame(String[] args) {
        log.info("启动游戏");
        GameEngine.launch(args);
    }
}
